﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using System.Management.Automation;
using System.Collections;
using System.Collections.ObjectModel;
using System.Diagnostics;
using PowerShellConsole.Util;

namespace PowerShellConsole.Jobs
{
    public class ScriptRunnerJob : SPJobDefinition
    {
        public ScriptRunnerJob() : base() { }

        public ScriptRunnerJob(string jobName, SPService service, SPServer server, SPJobLockType lockType)
            : base(jobName, service, server, lockType)
        {
        }

        public ScriptRunnerJob(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
        {
            this.Title = "Powershell Script Runner";
        }

        public override void Execute(Guid targetInstanceId)
        {
            foreach (SPSite site in WebApplication.Sites)
            {
                SPList scriptsList = null;
                foreach (SPList list in site.RootWeb.Lists)
                {
                    if (list.Title == "PowershellScripts")
                    {
                        scriptsList = site.RootWeb.Lists["PowershellScripts"];
                    }
                }
                if (scriptsList != null)
                {
                    SPQuery query = new SPQuery();
                    query.Query = "<Where><Eq><FieldRef Name=\"FileLeafRef\" /><Value Type=\"File\">" + Properties["script"] +
                        "</Value></Eq></Where>";
                    SPListItemCollection items = scriptsList.GetItems(query);
                    if (items.Count > 0)
                    {
                        SPListItem scriptItem = items[0];
                        string script = ASCIIEncoding.ASCII.GetString(scriptItem.File.OpenBinary());

                        SPSecurity.RunWithElevatedPrivileges(delegate
                        {
                            string source = "PowerShell Script Runner (" + Properties["script"] + ")";
                            try
                            {
                                RunspaceInvoke invoke = new RunspaceInvoke();
                                IList errors = new List<string>();
                                Collection<PSObject> results = invoke.Invoke(script, new List<string>(), out errors);

                                StringBuilder resultsString = new StringBuilder();
                                StringBuilder errorsString = new StringBuilder();

                                foreach (PSObject res in results)
                                {
                                    resultsString.Append(Convert.ToString(res) + "\r\n");
                                }
                                foreach (string err in errors)
                                {
                                    errorsString.Append(err + "\r\n");
                                }
                                TraceProvider.RegisterTraceProvider();
                                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.InformationEvent, Guid.Empty, "ScriptRunnerJob",
                                    "PSConsole", "ScriptJob", resultsString.ToString());
                                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.Exception, Guid.Empty, "ScriptRunnerJob",
                                    "PSConsole", "ScriptJob", errorsString.ToString());
                                TraceProvider.UnregisterTraceProvider();
                            }
                            catch (Exception ex)
                            {
                                TraceProvider.RegisterTraceProvider();
                                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.Exception, Guid.Empty, "ScriptRunnerJob",
                                    "PSConsole", "ScriptJob", ex.ToString());
                                TraceProvider.UnregisterTraceProvider();
                            }
                        });
                    }
                }
            }
        }
    }
}
